package com.hd.trans.files.repository;

import android.content.ContentResolver;
import android.database.Cursor;
import android.media.MediaMetadataRetriever;
import android.provider.MediaStore;
import android.text.TextUtils;

import com.hd.trans.files.bean.Video;
import com.hd.trans.files.model.FileSortModel;
import com.hd.trans.files.sort.MediaSortHelper;
import com.hd.trans.utils.FileUtils;
import com.hd.trans.utils.StorageUtils;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.core.SingleOnSubscribe;
import io.reactivex.rxjava3.schedulers.Schedulers;

/**
 * Author: yangtianwen
 * Time: 2021/12/14
 * Des: 视频数据源
 */
public class VideoDataRepository {

    //支持的视频格式
    private static final String[] VIDEO_FORMAT = new String[]{"mp4"};

    private final File mSdRootPath = new File(FileUtils.getStorageDirectory());
    private final String mRootPath = mSdRootPath.getPath();

    private final LocalVideoProvider mLocalVideoProvider = new LocalVideoProvider();

    private final MediaMetadataRetriever mMetadataRetriever = new MediaMetadataRetriever();

    public @NonNull Single<List<Video>> searchVideoWithKeyword(
            List<String> scanDir,
            String keyWord,
            FileSortModel.ModeItem sortModeItem,
            LocalVideoProvider.ScanFileInterface listener
    ) {
        return Single.create((SingleOnSubscribe<List<Video>>) emitter -> {
            mLocalVideoProvider.setScanFileInterface(listener);
            emitter.onSuccess(mLocalVideoProvider.searchVideo(scanDir, keyWord));
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 从文件路径获取视频数据
     *
     * @param path 路径
     */
    public Single<List<Video>> requestVideosWithDir(String path, FileSortModel.ModeItem sortModeItem) {
        return taskRequestVideosWithDir(path)
                .map(videos -> MediaSortHelper.getInstance().sortVideo(videos, sortModeItem))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    private Single<List<Video>> taskRequestVideosWithDir(String path) {
        return Single.create(emitter -> {
            List<Video> videos = new ArrayList<>();
            File currentFile = getCurrentFile(path);
            File[] files = currentFile.listFiles(mFileFilter);
            if (files == null || files.length <= 0) {
                emitter.onSuccess(videos);
            }
            File storageDir = new File(StorageUtils.getStorageDirectory());
            // 遍历这个路径下所有的文件夹和文件
            for (File file : files) {
                if (file.isDirectory()) {
                    // 判断该文件是否是文件夹并且屏蔽程序自身的文件夹
                    if (isFilterDirectoryOrFile(file.getName())) {
                        continue;
                    }
                    if (!file.getParent().equals(storageDir.getParent())
                            || file.getPath().equals(storageDir.getPath())) {
                        videos.add(createVideo(file, true));
                    }
                } else if (file.isFile() && isAvailableVideo(file.getAbsolutePath())) {
                    Video video = createVideo(file, false);
//                    video.setDuration(AudioUtils.getMusicItemDuration(file.getPath(), mMetadataRetriever));
                    videos.add(video);
                }
            }
            emitter.onSuccess(videos);
        });
    }

    private Video createVideo(File file, boolean isDir) {
        Video video = new Video(0, file.getName(), file.getPath(), file.lastModified(), 0, file.length());
//        video.setName(file.getName());
//        video.setPath(file.getPath());
//        video.setDate(file.lastModified());
        video.setIsDirectory(isDir);
        return video;
    }

    private boolean isAvailableVideo(String path) {
        if (!TextUtils.isEmpty(path)) {
            File file = new File(path);
            return checkValidExtVideoFile(path) && file.exists();
        } else {
            return false;
        }
    }

    public boolean checkValidExtVideoFile(String strPath) {
        if (!TextUtils.isEmpty(strPath)) {
            for (String format : VIDEO_FORMAT) {
                if (strPath.toLowerCase().endsWith(format.toLowerCase())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 过滤文件
     */
    private boolean isFilterDirectoryOrFile(String name) {
        return name.equals("17rd") || name.equals("proc");
    }

    /**
     * 过滤文件
     */
    private final FileFilter mFileFilter = pathname -> !pathname.isHidden();

    private File getCurrentFile(String url) {
        if (!url.equals(mRootPath)) {
            // 获取这个路径下的所有文件及目录
            return new File(url);
        } else {
            // 获取根目录File对象
            return new File(mRootPath);
        }
    }


    /**
     * 通过 ContentProvider 获取本地视频
     */
    public Single<List<Video>> requestVideos(ContentResolver contentResolver, FileSortModel.ModeItem sortModeItem) {
        return taskRequestVideo(contentResolver)
                .map(videos -> MediaSortHelper.getInstance().sortVideo(videos, sortModeItem))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    private Single<List<Video>> taskRequestVideo(ContentResolver contentResolver) {
        return Single.create(
                emitter -> emitter.onSuccess(loadVideoByContentProvider(contentResolver))
        );
    }

    private List<Video> loadVideoByContentProvider(ContentResolver mContentResolver) {
        List<Video> videoList = new ArrayList<>();
        try (Cursor cursor = mContentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                null, null, null,
                MediaStore.Video.Media.DEFAULT_SORT_ORDER)) {
            while (cursor.moveToNext()) {
                // 路径
                String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
                if (!FileUtils.isExists(path)) {
                    continue;
                }
                // 时长
                long duration = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));
                if (duration > 0) {
                    // 视频的id
                    int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
                    // 视频名称
                    String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME));
                    //分辨率
                    String resolution = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.RESOLUTION));
                    // 大小
                    long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
                    //修改时间
                    String time = change((int) duration / 1000);
                    long date = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_MODIFIED));
                    Video video = new Video(id, path, name, resolution, size, date, duration, null, time);
                    videoList.add(video);
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return videoList;
    }

    /*        * 将秒数转为时分秒        * */
    public String change(int second) {
        int h = 0;
        int d = 0;
        int s = 0;
        String H = "";
        String D = "";
        String S = "";
        int temp = second % 3600;
        if (second > 3600) {
            h = second / 3600;
            if (temp != 0) {
                if (temp > 60) {
                    d = temp / 60;
                    if (temp % 60 != 0) {
                        s = temp % 60;
                    }
                } else {
                    s = temp;
                }

            }
        } else {
            d = second / 60;
            if (second % 60 != 0) {
                s = second % 60;
            }
        }
        if (0 < h && h < 10) {
            H = 0 + "" + h;
        }
        if (h >= 10) {
            H = h + "";
        }
        if (h == 0) {
            H = "00";
        }

        if (0 < d && d < 10) {
            D = 0 + "" + d;
        }
        if (d >= 10) {
            D = "" + d;
        }
        if (d == 0) {
            D = "00";
        }

        if (0 < s && s < 10) {
            S = 0 + "" + s;
        }
        if (s >= 10) {
            S = "" + s;
        }
        if (s == 0) {
            S = "00";
        }

        if (h != 0) {
            return H + ":" + D + ":" + S;
        } else {
            return D + ":" + S;
        }
    }
}
